<template>
  <div class="import-extra-data">
    <div class="table-area">
      <div class="table-toolbar">
        <div class="title-left">
          <a-tooltip placement="top">
            <template slot="title">
              <p>喜欢低于50：12分<br>
                喜欢51-199：14分<br>
                喜欢200-299：16分+20分<br>
                喜欢300以上：18分+30分</p>
            </template>
            <h3><strong>未打分列表</strong>&nbsp;&nbsp;&nbsp;&nbsp;打分规则
              <a-icon type="question-circle" />
            </h3>
          </a-tooltip>
        </div>
        <a-upload accept=".xlsx,.xls" :before-upload="handleBeforeUpload" :show-upload-list="false"
          :disabled="importLoading || executing">
          <a-button type="primary" style="margin-right: 8px" :loading="importLoading">
            <a-icon type="upload" />导入数据
          </a-button>
        </a-upload>
        <a-button type="primary" :disabled="!importData.length || importLoading" :loading="executing"
          @click="handleExecute">
          <a-icon type="play-circle" />执行
        </a-button>
        <a-button type="primary" :loading="loading" style="margin-left: 8px" @click="getTableData">
          <a-icon type="reload" />刷新
        </a-button>
      </div>
      <vxe-table ref="xTable" :loading="loading" :data="tableData" :auto-resize="true" :height="listTableHeight"
        resizable show-overflow="tooltip">
        <vxe-column field="contribution_id" width="60" title="id" />
        <vxe-column field="title" title="作品名" />
        <vxe-column field="submission_date" title="提交时间">
          <template v-slot="{ row }">
            {{ formatDate(row.submission_date) }}
          </template>
        </vxe-column>
        <vxe-column field="titlePlantform" title="导入作品名" />
        <vxe-column field="channels_likes" title="点赞数" width="80">
          <template v-slot="{ row }">
            {{ row.channels_likes || '-' }}
          </template>
        </vxe-column>
        <vxe-column field="matched" title="是否匹配" width="80">
          <template v-slot="{ row }">
            <a-tag v-if="row.matched" color="green">
              是
            </a-tag>
            <a-tag v-else-if="row.matched===false" color="red">
              否
            </a-tag>
            <a-tag v-else color="orange">
              等待
            </a-tag>
          </template>
        </vxe-column>
        <vxe-column field="similarity" title="相似度" width="80" />
        <vxe-column field="matchedScore" title="匹配分值" width="100" />
        <vxe-column field="platform_submit_date" title="发布时间" width="100" />
        <vxe-column field="likeStatus" title="喜欢数据写入情况" min-width="200">
          <template v-slot="{ row }">
            <a-tag v-if="row.likeStatus" color="green">
              成功
            </a-tag>
            <a-tag v-else-if="row.likeStatus == false" color="red">
              错误
            </a-tag>
            <a-tag v-else color="orange">
              等待
            </a-tag>
            <span>{{row.likeMessage}}</span>
          </template>
        </vxe-column>
        <vxe-column field="scoreStatus" title="打分执行情况" min-width="200">
          <template v-slot="{ row }">
            <a-tag v-if="row.scoreStatus" color="green">
              成功
            </a-tag>
            <a-tag v-else-if="row.scoreStatus == false" color="red">
              错误
            </a-tag>
            <a-tag v-else color="orange">
              等待
            </a-tag>
            <span>{{row.scoreMessage}}</span>
          </template>
        </vxe-column>
      </vxe-table>
    </div>
  </div>
</template>

<script>
  import {
    apiContributionList,
    apiContributionImportPlatformData,
    apiContributionScore
  } from '@/api/featch'
  import moment from 'moment'
  import XLSX from 'xlsx'

  export default {
    name: 'ScoreExtraData',
    data() {
      return {
        // 表格数据
        tableData: [],
        loading: false,
        listTableHeight: null,

        // 导入相关
        importData: [],
        importLoading: false,
        executing: false,
      }
    },
    mounted() {
      this.initTableHeight()
      this.getTableData()

      // 监听窗口大小变化
      window.addEventListener('resize', this.initTableHeight)
    },
    beforeDestroy() {
      window.removeEventListener('resize', this.initTableHeight)
    },
    methods: {
      /**
       * @description 初始化表格高度
       */
      initTableHeight() {
        const clientHeight = document.documentElement.clientHeight
        // 列表表格高度：页面高度 - 头部高度(64px) - main容器margin(24px * 2) - main容器padding(24px * 2) - tabs高度(44px) - 导出按钮区域(56px)
        this.listTableHeight = clientHeight - 64 - 48 - 48 - 44 - 56
      },
      /**
       * @description 获取表格数据
       */
      async getTableData() {
        this.importData = []
        this.loading = true
        try {
          const res = await apiContributionList({
            page: 1,
            page_size: 100,
            is_scored: 0,
            approved_status: 1
          })
          if (res.code === 200) {
            this.tableData = res.data.list || []
          } else {
            this.$message.error(res.message)
          }
        } catch (err) {
          this.$message.error(err.toString())
        }
        this.loading = false
      },
      /**
       * @description 格式化日期
       */
      formatDate(date) {
        if (!date) return ''
        return moment(date).format('YYYY-MM-DD HH:mm:ss')
      },
      /**
       * @description 上传前处理
       */
      handleBeforeUpload(file) {
        this.importLoading = true
        const reader = new FileReader()
        reader.onload = (e) => {
          try {
            const data = new Uint8Array(e.target.result)
            const workbook = XLSX.read(data, {
              type: 'array'
            })
            const firstSheetName = workbook.SheetNames[0]
            const worksheet = workbook.Sheets[firstSheetName]
            const results = XLSX.utils.sheet_to_json(worksheet)

            function excelDateToYYYYMMDD(excelDate) {
              // 从 1900-01-01 开始计算，减去 1 天修正 Excel 的 1900 年闰年 bug
              return moment('1900-01-01')
                .add(excelDate - 2, 'days')
                .format('YYYY/MM/DD');
            }

            // 转换数据格式
            this.importData = results.map(item => ({
              title: item['视频描述'],
              likes: item['喜欢'],
              platform_submit_date: excelDateToYYYYMMDD(item['发布时间'])
            }))

            console.log(this.importData)
            // 执行匹配
            this.tableData = this.matchArrays(this.tableData, this.importData)

            this.$message.success('数据导入成功')

          } catch (err) {
            this.$message.error('文件解析失败')
            console.error(err)
          }
          this.importLoading = false
        }
        reader.readAsArrayBuffer(file)
        return false
      },
      /**
       * @description 匹配
       */
      matchArrays(arr1, arr2) {
        // 复用之前的字符串处理函数
        function processString(str) {
          if (typeof str !== 'string') return '';
          let processed = str.replace(/[\r\n]+/g, ''); // 去除换行

          // 只去除半角括号()和全角括号（）及其中的内容
          // 严格匹配成对的括号：半角() 和 全角（）
          processed = processed.replace(/\(.*?\)|（.*?）/g, '');

          processed = processed.replace(/#\S+/g, ''); // 去除话题
          return processed.trim().replace(/\s+/g, ' '); // 清理空格
        }

        // 复用编辑距离计算相似度函数
        function calculateSimilarity(str1, str2) {
          if (str1 === str2) return 1;
          const len1 = str1.length;
          const len2 = str2.length;
          const maxLen = Math.max(len1, len2);
          if (maxLen === 0) return 1;

          const matrix = Array.from({
            length: len1 + 1
          }, () => Array(len2 + 1).fill(0));
          for (let i = 0; i <= len1; i++) matrix[i][0] = i;
          for (let j = 0; j <= len2; j++) matrix[0][j] = j;

          for (let i = 1; i <= len1; i++) {
            for (let j = 1; j <= len2; j++) {
              const cost = str1[i - 1] === str2[j - 1] ? 0 : 1;
              matrix[i][j] = Math.min(
                matrix[i - 1][j] + 1,
                matrix[i][j - 1] + 1,
                matrix[i - 1][j - 1] + cost
              );
            }
          }
          return 1 - matrix[len1][len2] / maxLen;
        }

        // 存储匹配结果（包含原始信息和匹配状态）
        const result = [];
        // 记录已匹配的arr2索引，避免重复匹配
        const matchedIndices = new Set();

        // 遍历arr1中的每个元素
        for (const item1 of arr1) {
          const processedTitle1 = processString(item1.title);
          let bestMatch = null;
          let highestSimilarity = 0;
          let bestIndex = -1;

          // 遍历arr2寻找最相似的元素
          for (let i = 0; i < arr2.length; i++) {
            // 跳过已匹配的元素
            if (matchedIndices.has(i)) continue;

            const item2 = arr2[i];
            const processedTitle2 = processString(item2.title);
            const similarity = calculateSimilarity(processedTitle1, processedTitle2);

            // 记录最高相似度且达标的匹配项
            if (similarity >= 0.7 && similarity > highestSimilarity) {
              highestSimilarity = similarity;
              bestMatch = item2;
              bestIndex = i;
            }
          }

          // 处理匹配结果
          if (bestMatch) {
            matchedIndices.add(bestIndex);
            result.push(Object.assign(item1, {
              titlePlantform: bestMatch.title,
              platform_submit_date: bestMatch.platform_submit_date,
              matched: true,
              similarity: highestSimilarity,
              channels_likes: bestMatch.likes, // 赋值匹配项的like
              matchedScore: this.calculateScore(bestMatch.likes, )
            }));
          } else {
            result.push(Object.assign(item1, {
              titlePlantform: null,
              platform_submit_date: null,
              matched: false,
              similarity: 0,
              channels_likes: 0 // 赋值匹配项的like
            }));
          }
        }
        return result;
      },
      /**
       * @description 根据like返回分值
       */
      calculateScore(like) {
        // 确保输入为有效数字，非数字或负数按0处理
        const likeNum = typeof like === 'number' && !isNaN(like) ? Math.max(0, Math.floor(like)) : 0;

        if (likeNum <= 50) {
          return 12;
        } else if (likeNum >= 51 && likeNum <= 199) {
          return 14;
        } else if (likeNum >= 200 && likeNum <= 299) {
          return 16 + 20; // 36分
        } else if (likeNum >= 300) {
          return 18 + 30; // 48分
        }
      },
      /**
       * @description 执行
       */
      async handleExecute() {
        if (!this.importData.length) {
          this.$message.warning('请先导入数据')
          return
        }

        this.executing = true
        // 写入数据
        try {
          for (let i = 0; i < this.tableData.length; i++) {
            const item = this.tableData[i]
            if (item.matched) {
              try {
                const channels_likes = parseInt(item.channels_likes) || 0

                const res = await apiContributionImportPlatformData({
                  contribution_id: item.contribution_id,
                  channels_likes,
                  platform_submit_date: item.platform_submit_date,
                })

                if (res.code === 200) {
                  this.$set(this.tableData[i], 'likeStatus', true)
                  this.$set(this.tableData[i], 'likeMessage', res.message)
                  // this.tableData[i].likeStatus = true
                  // this.tableData[i].likeMessage = res.message
                } else {
                  this.$set(this.tableData[i], 'likeStatus', false)
                  this.$set(this.tableData[i], 'likeMessage', res.message)
                  // this.tableData[i].likeStatus = false
                  // this.tableData[i].likeMessage = res.message
                }
              } catch (err) {
                this.$set(this.tableData[i], 'likeStatus', false)
                this.$set(this.tableData[i], 'likeMessage', err.message)
                // this.tableData[i].likeStatus = false
                // this.tableData[i].likeMessage = err.message
              }
            }
          }
        } catch (err) {
          console.log(err)
          this.$message.error('导入过程出错')
        } finally {
          this.executing = false
        }
        // 打分
        try {
          for (let i = 0; i < this.tableData.length; i++) {
            const item = this.tableData[i]
            if (item.matched) {
              try {
                const res = await apiContributionScore({
                  contribution_id: item.contribution_id,
                  score: item.matchedScore
                })

                if (res.code === 200) {
                  this.$set(this.tableData[i], 'scoreStatus', true)
                  this.$set(this.tableData[i], 'scoreMessage', res.message)
                } else {
                  this.$set(this.tableData[i], 'scoreStatus', false)
                  this.$set(this.tableData[i], 'scoreMessage', res.message)
                }
              } catch (err) {
                this.$set(this.tableData[i], 'scoreStatus', false)
                this.$set(this.tableData[i], 'scoreMessage', err.message)
              }
            }
          }
        } catch (err) {
          console.log(err)
          this.$message.error('导入过程出错')
        } finally {
          this.executing = false
        }
      },
      /**
       * @description 获取状态文字
       */
      getStatusText(status) {
        const statusMap = {
          'success': '导入成功',
          'error': '导入失败'
        }
        return statusMap[status] || '未知状态'
      },
      /**
       * @description 获取状态颜色
       */
      getStatusColor(status) {
        const colorMap = {
          'success': 'green',
          'error': 'red'
        }
        return colorMap[status] || 'default'
      },
    }
  }
</script>

<style lang="less" scoped>
  .import-extra-data {
    height: 100%;

    .table-area {
      background: #fff;
      border-radius: 4px;

      .table-toolbar {
        .title-left {
          float: left;
        }

        padding: 16px 24px;
        text-align: right;
      }
    }
  }
</style>